
#include <windows.h>
#include <oal.h>
#include <bsp.h>

#include "ModuleExport.h"

void TimerHdl(BYTE bMain, BYTE bSysCtrl, BYTE bIntrType);



pfnTimerHdl g_pfnTimerHdlS[5]={0};
void* 	g_pvHldArgS[5]={0};
DWORD	g_dwTimeValS[5]={0};

volatile DWORD* g_pTimerRegs = NULL;

void ChipInit_Timer()
{
	BYTE i;

	g_pTimerRegs = (DWORD*)OALPAtoUA(AK_BASE_REG_PA_TIMER);					//uncached
	g_pTimerRegs+=TIMER1_CTRL_OFFSET/4;

	for(i=0; i<5; i++)
	{
		Intr_RegHdl(27, 21-i, TimerHdl);
	}

}

void TimerHdl(BYTE bMain, BYTE bSysCtrl, BYTE bIntrType)
{
	BYTE bTimer=21-bSysCtrl;

	if(g_pfnTimerHdlS[bTimer])
	{
		REG32(g_pTimerRegs+bTimer) = TIMER_CTRL_CLEAR;

		(*g_pfnTimerHdlS[bTimer])(g_pvHldArgS[bTimer]);

		REG32(g_pTimerRegs+bTimer) = g_dwTimeValS[bTimer];
		REG32(g_pTimerRegs+bTimer) |= TIMER_CTRL_EN | TIMER_CTRL_LOAD;

		Intr_EnHdl(bMain, bSysCtrl, bIntrType, TRUE);
	}
	else
	{
		REG32(g_pTimerRegs+bTimer) &= (~TIMER_CTRL_EN);
		Intr_EnHdl(bMain, bSysCtrl, bIntrType, FALSE);
	}
}


BOOL Timer_Start(BYTE bTimer, BYTE bIntrType, BOOL fStart, DWORD dwTimeUs, pfnTimerHdl pfnHdl, void* pv)
{
	volatile DWORD* pTimerReg;

	if(bTimer>4)
	{
		return FALSE;
	}

	pTimerReg=g_pTimerRegs+bTimer;

	if(fStart)
	{
		if(!pfnHdl)
		{
			return FALSE;
		}
		g_pfnTimerHdlS[bTimer]=pfnHdl;
		g_pvHldArgS[bTimer]=pv;
		g_dwTimeValS[bTimer]=TIMER_CTRL_CNT(dwTimeUs*12);

		// clear timer first, or it will start delay
		REG32(pTimerReg) = TIMER_CTRL_CLEAR;
		// Set timer register,don't calc the counts,need fix
		REG32(pTimerReg) =  g_dwTimeValS[bTimer];
		REG32(pTimerReg) |= TIMER_CTRL_EN | TIMER_CTRL_LOAD;
	}
	else
	{
		REG32(pTimerReg) &= ~TIMER_CTRL_EN;
		g_pfnTimerHdlS[bTimer]=NULL;
		g_pvHldArgS[bTimer]=NULL;
	}

	Intr_EnHdl(27, 21-bTimer, bIntrType, fStart);

	return TRUE;
}

